# SPDS
library(tidyverse)
library(sf)
library(units)
library(readxl)

# Data
library(USAboundaries)
library(rnaturalearth)

# Visualization
library(gghighlight)
library(ggrepel)
library(knitr)

Question 1

1.1 Define a Projection- North America Equidistant Conic

Equidistant preserves distance

eqdc = '+proj=eqdc +lat_0=40 +lon_0=-96 +lat_1=20 +lat_2=60 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs'

1.2 Get USA State Boundaries

conus= USAboundaries::us_states(resolution = "low") %>% 
  filter(!name %in% c("Hawaii", "Alaska", "Puerto Rico")) %>% 
  st_transform(eqdc)

1.3 Get County Boundaries for Mexico, USA, and Canada

countries= rnaturalearth::countries110 %>% 
  st_as_sf(countries) %>%  
  filter(admin %in% c("United States of America", "Mexico", "Canada")) %>% 
  st_transform(eqdc)

1.4 Get City Locations from the CSV File

url = 'https://raw.githubusercontent.com/mikejohnson51/exercise-04/master/data/uscities.csv'
us_cities = readr::read_csv(url) %>% 
  filter(!state_name %in% c("Hawaii", "Puerto Rico", "Alaska")) %>% 
  st_as_sf(coords= c("lng", "lat"), crs= 4326) %>% 
  st_transform(eqdc)

Question 2

2.1 Distance to USA Border (Coastline or National) [km]

conus = USAboundaries::us_states() %>%
  filter(!state_name %in% c("Puerto Rico",
                            "Alaska",
                            "Hawaii")) 
conus <- st_transform(conus, eqdc)

us_border = st_union(conus) %>%
    st_cast("MULTILINESTRING")
plot(us_border)

border_distances= us_cities %>% 
  mutate(distance_border= st_distance(., us_border),
  distance_border= units::set_units(distance_border, "km"),
  distance_border= as.numeric(distance_border))

table2.1= border_distances %>% 
  select("city", "state_name", "distance_border") %>% 
  slice_max(distance_border, n= 10)  

  
knitr::kable(table2.1,
              caption= "10 Furthest Cities from USA Border",
              col.names= c( "City", "State Name", "Distance to Border [km]", "Longitude and Latitude"),
             format.args = list(big.mark = ",")) %>% 
              
kableExtra::kable_styling("basic", full_width = TRUE, font_size = 14)
10 Furthest Cities from USA Border
City State Name Distance to Border [km] Longitude and Latitude
Dresden Kansas 1,012.3168 POINT (-356571.4 -33326.4)
Herndon Kansas 1,007.7498 POINT (-384490.3 16.57081)
Hill City Kansas 1,005.1465 POINT (-311590.8 -63668.04)
Atwood Kansas 1,004.7343 POINT (-405636.9 -9836.669)
Jennings Kansas 1,003.6460 POINT (-346143.8 -27290.37)
Oberlin Kansas 1,002.5548 POINT (-364489.1 -10570.27)
Morland Kansas 1,002.4886 POINT (-330148.7 -64892.93)
Selden Kansas 998.3952 POINT (-368976 -41639.3)
Lenora Kansas 996.1404 POINT (-322966.2 -36106.03)
Parks Nebraska 995.1534 POINT (-458911.3 19303.77)

2.2 Distance to States [km]

conus = USAboundaries::us_states() %>%
  filter(!state_name %in% c("Puerto Rico",
                            "Alaska",
                            "Hawaii")) 
conus <- st_transform(conus, eqdc)


state_border=  st_combine(conus) %>%
    st_cast("MULTILINESTRING")
plot(state_border)

border_distances_state= us_cities %>% 
  mutate(statedistance_border= st_distance(., state_border),
  statedistance_border= units::set_units(statedistance_border, "km"),
  statedistance_border= as.numeric(statedistance_border))

table2.2= border_distances_state %>% 
  select( "city", "state_name","statedistance_border") %>% 
  slice_max(statedistance_border, n= 10)

knitr::kable(table2.2,
              caption= "Distance from Cities to State Borders",
              col.names= c("City", "State Name", "Distance to Border[km]", "Longitude and Latitude"),
              format.args= list(big.mark= ".")) %>% 
  kableExtra::kable_styling("basic", full_width = TRUE, font_size = 14)
Distance from Cities to State Borders
City State Name Distance to Border[km] Longitude and Latitude
Lampasas Texas 308.9216 POINT (-198945 -989071.5)
Bertram Texas 302.8190 POINT (-188513.4 -1024935)
Kempner Texas 302.5912 POINT (-179804.5 -988233.6)
Harker Heights Texas 298.8125 POINT (-149930.5 -990857.1)
Florence Texas 298.6804 POINT (-163913.8 -1014611)
Killeen Texas 298.0399 POINT (-157658.8 -988684.5)
Belton Texas 297.4946 POINT (-134851.6 -991637.3)
Salado Texas 297.2807 POINT (-139526.1 -1003347)
Copperas Cove Texas 296.6332 POINT (-174353 -983503.9)
Nolanville Texas 296.3474 POINT (-146658.4 -988886.4)

2.3 Distance to Mexico [km]

mex= countries %>% 
  filter(admin %in% 'Mexico')
  
 mex_border= st_union(mex) %>%
    st_cast("MULTILINESTRING")
plot(mex_border)

mex_distance= us_cities %>% 
  mutate(mex_dis_border=st_distance(., mex),
         mex_dis_border=units::set_units(mex_dis_border, "km"),
  mex_dis_border= as.numeric(mex_dis_border))

table2.3= mex_distance %>% 
  select("city", "state_name", "mex_dis_border") %>% 
  slice_max(mex_dis_border, n=10)

knitr::kable(table2.3,
              caption= "Top 10 Furthest Cities from Mexico Border",
              col.names= c("City", "State Name",  "Distance to Border[km]", "Longitude and Latitude"),
              format.args= list(big.mark= ".")) %>% 
kableExtra::kable_styling("basic", full_width = TRUE, font_size = 14)
Top 10 Furthest Cities from Mexico Border
City State Name Distance to Border[km] Longitude and Latitude
Caribou Maine 3.250.334 POINT (1981398 1070430)
Presque Isle Maine 3.234.570 POINT (1987753 1051523)
Calais Maine 3.134.348 POINT (2093840 904408.7)
Eastport Maine 3.125.624 POINT (2115970 885912.2)
Old Town Maine 3.048.366 POINT (1994091 851089.5)
Bangor Maine 3.035.115 POINT (1993261 837236.6)
Brewer Maine 3.033.384 POINT (1998796 833281.7)
Ellsworth Maine 3.027.538 POINT (2022983 817662.3)
Belfast Maine 2.988.595 POINT (1989192 789001.2)
Waterville Maine 2.970.264 POINT (1940367 787741.7)

2.4 Distance to Canada [km]

can= countries %>% 
  filter(admin %in% 'Canada')
(can_border = st_union(can) %>%
    st_cast("MULTILINESTRING"))
## Geometry set for 1 feature 
## Geometry type: MULTILINESTRING
## Dimension:     XY
## Bounding box:  xmin: -2393433 ymin: 262079.3 xmax: 2982938 ymax: 4936902
## CRS:           +proj=eqdc +lat_0=40 +lon_0=-96 +lat_1=20 +lat_2=60 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs
plot(can_border)

can_distance= us_cities %>% 
  mutate(can_dis_border=st_distance(., can_border),
         can_dis_border=units::set_units(can_dis_border, "km"),
  can_dis_border= as.numeric(can_dis_border))

table2.4= can_distance %>% 
  select("city","state_name","can_dis_border") %>% 
  slice_max(can_dis_border, n=10)

knitr::kable(table2.4,
              caption= "Top 10 Furthest Cities from Canada Border",
              col.names= c("City", "State Name", "Distance to Border[km]", "Longitude and Latitude"),
              format.args= list(big.mark= ".")) %>% 
kableExtra::kable_styling("basic", full_width = TRUE, font_size = 14)
Top 10 Furthest Cities from Canada Border
City State Name Distance to Border[km] Longitude and Latitude
Guadalupe Guerra Texas 2.206.455 POINT (-298391.5 -1502124)
Sandoval Texas 2.205.641 POINT (-298121.8 -1501313)
Fronton Texas 2.204.784 POINT (-297774.7 -1500505)
Fronton Ranchettes Texas 2.202.118 POINT (-293005.2 -1500698)
Evergreen Texas 2.202.020 POINT (-292736.4 -1500773)
Ramos Texas 2.201.882 POINT (-293014.6 -1500398)
Roma Texas 2.201.784 POINT (-291033.9 -1501728)
Loma Vista Texas 2.200.410 POINT (-288642.4 -1501773)
Moraida Texas 2.200.328 POINT (-288194.4 -1501999)
J.F. Villareal Texas 2.199.994 POINT (-288379.9 -1501449)

Question 3

3.1 Data

borders = st_combine(countries) %>%
    st_cast("MULTILINESTRING")
plot(borders)

state_border=  st_combine(conus) %>%
    st_cast("MULTILINESTRING")
plot(state_border)

max_pop= us_cities %>% 
  slice_max(population, n= 10)

ggplot() + 
  geom_sf(data = borders, aes()) + 
  geom_sf(data=state_border, aes())+
  geom_sf(data= max_pop, aes(), col="coral1") + 
  ggrepel::geom_label_repel(
    data = max_pop,
    aes(label = city, geometry = geometry),
    stat = "sf_coordinates",
    size = 3) +
  labs(title = "10 Cities with Largest Populations",
       subtitle =" In the United States") + 
  ggthemes::theme_map() 

## 3.2 City Distance from the Border

borders = st_combine(countries) %>%
    st_cast("MULTILINESTRING")
plot(borders)

state_border=  st_combine(conus) %>%
    st_cast("MULTILINESTRING")
plot(state_border)

border_distances= us_cities %>% 
  mutate(distance_border= st_distance(., us_border),
  distance_border= units::set_units(distance_border, "km"),
  distance_border= as.numeric(distance_border))

top_5= border_distances %>% 
  slice_max(distance_border, n=5)

ggplot() + 
  geom_sf(data = border_distances, aes(col= distance_border)) +
  scale_color_gradient(low= "yellowgreen", high= "red1")+
  geom_sf(data=top_5, aes(), col= "red4")+
  geom_sf(data = us_border, aes()) + 
  ggrepel::geom_label_repel(
    data = top_5,
    aes(label = city, geometry = geometry),
    stat = "sf_coordinates",
    size = 3) +
  labs(title = "5 Cities Furthest from US National Border",
       col= "Distance to Border [km]") + 
  ggthemes::theme_map()+
theme(legend.position = "right")

## 3.3 City Distnace from Nearest State

state_border=  st_combine(conus) %>%
    st_cast("MULTILINESTRING")
plot(state_border)

border_distances_state= us_cities %>% 
  mutate(statedistance_border= st_distance(., state_border),
  statedistance_border= units::set_units(statedistance_border, "km"),
  statedistance_border= as.numeric(statedistance_border))
ggplot() + 
  geom_sf(data = border_distances_state, aes(col= statedistance_border)) +
  scale_color_gradient(low= "yellowgreen", high= "red1")+
  geom_sf(data=top_5, aes(), col= "red4")+
  geom_sf(data = state_border, aes()) + 
  ggrepel::geom_label_repel(
    data = top_5,
    aes(label = city, geometry = geometry),
    stat = "sf_coordinates",
    size = 3) +
  labs(title = "City Distance from State Border",
         subtitle= "5 Cities Furthest from US National Border",
       col= "Distance to State Border [km]") + 
  ggthemes::theme_map()+
theme(legend.position = "right")

## Equidistance Boundary from Mexico and Canada

city3.4= us_cities %>% 
  select(city, state_name, population, geometry)

uscities3.4= city3.4 %>% 
  filter(!state_name %in% c("Alaska", "Hawaii", "Puerto Rico")) %>% 
  st_as_sf(coords= c("lng", "lat"), crs= 4326) %>% 
    st_transform(eqdc)
  

mex_can_dis= uscities3.4 %>% 
  mutate(can_dis= st_distance(uscities3.4, can_border),
         can_dis= units::set_units(can_dis, "km"),
         can_dis= as.numeric(can_dis)) %>% 
  ungroup() %>% 
  mutate(mex_dis= st_distance(uscities3.4, mex_border),
         mex_dis= units::set_units(mex_dis, "km"),
         mex_dis= as.numeric(mex_dis)) %>% 
  ungroup()

ab= mex_can_dis %>%   
  mutate(ab_dis= abs(can_dis - mex_dis)) %>% 
  select(city, state_name, population, can_dis, mex_dis, ab_dis)

pop_3.4 <- ab %>% 
  filter(ab_dis <= 100) %>% 
  slice_max(population, n=5)


ggplot() + 
  geom_sf(data = borders, aes()) + 
  geom_sf(data=state_border, aes())+
  geom_sf(data= ab, aes(col= ab_dis)) +
  gghighlight::gghighlight(ab_dis <= 100)+
geom_sf(data= pop_3.4, aes(), col= "coral1") +
  ggrepel::geom_label_repel(
    data = pop_3.4,
    aes(label = city, geometry = geometry),
    stat = "sf_coordinates",
    size = 3) +
  labs(title = "US Cities 100km from Mexico and Canada Border",
       subtitle ="5 Most Populous Cities within this Zone") + 
  ggthemes::theme_map() 

# Question 4 ## 4.1 Quantifing Border Zone

border_distances= us_cities %>% 
  mutate(distance_border= st_distance(., us_border),
  distance_border= units::set_units(distance_border, "km"),
  distance_border= as.numeric(distance_border)) %>% 
  filter(distance_border <= 160) %>% 
  select(city, state_name, population, distance_border, geometry)  
  
 
city_100zone= nrow(border_distances)
pop_tot= sum(border_distances$population)
pop_percent= (pop_tot/ sum(us_cities$population) *100) %>% 
  round(digits=2)
 
table4.1= data.frame(Description= c("Number of Cities within 100mi Zone", "Total Population within 100mi Zone", "Percent of Continental US within 100mi Zone"), Numbers= c(city_100zone, pop_tot, pop_percent))
knitr::kable(table4.1,
              caption= "Information about 100 mile Zone of US Border") %>% 
kableExtra::kable_styling("basic", full_width = TRUE, font_size = 14)
Information about 100 mile Zone of US Border
Description Numbers
Number of Cities within 100mi Zone 12283.00
Total Population within 100mi Zone 259935815.00
Percent of Continental US within 100mi Zone 65.44

4.2 Mapping Border Zone

city_pop= border_distances %>% 
  filter(distance_border <= 160) %>% 
  group_by(state_name) %>% 
  slice_max(population, n= 10)

buffer100= border_distances %>% 
  filter(distance_border <= 160) 



ggplot()+
  geom_sf(data= state_border, aes())+
    geom_sf(data= buffer100, aes(col= distance_border))+
  scale_color_gradient(low= "orange", high= "darkred")+
  ggrepel::geom_label_repel(
    data = city_pop,
    aes(label = city, geometry = geometry),
    stat = "sf_coordinates",
    size = 3) +
  labs(title = "Top 10 Most Populous Cities in 100mile Zone",
       col= "Distance from Border") + 
  ggthemes::theme_map()+
theme(legend.position = "right")